package xin.ukey.module.shiro.credentials;

import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.ByteSource;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 描述：密码匹配器
 *
 * @author ssl
 * @create 2017/11/06 8:57
 */
public class RetryLimitHashedCredentialsMather extends HashedCredentialsMatcher {
    /**
     * 😶密码错误次数缓存记录
     */
    private Cache<String, AtomicInteger> passwordRetryCache;

    public RetryLimitHashedCredentialsMather(CacheManager cacheManager) {
        passwordRetryCache = cacheManager.getCache("passwordRetryCache");
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        String userName = (String) token.getPrincipal();
        /** 获取当前用户登录失败的次数 */
        AtomicInteger retryCount = passwordRetryCache.get(userName);
        if (null == retryCount) {
            retryCount = new AtomicInteger(0);
            passwordRetryCache.put(userName, retryCount);
        }
        if (retryCount.incrementAndGet() > 5) {
            throw new ExcessiveAttemptsException("登录次数超过5次，请十分钟后再尝试登录");
        }
        boolean matches = super.doCredentialsMatch(token, info);
        if (matches) {
            /** 登录成功，清除错误登录次数 */
            passwordRetryCache.remove(userName);
        }
        return matches;
    }

    public String buildCredentials(String userName, String password, String credentialsSalt) {
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, password,
                ByteSource.Util.bytes(credentialsSalt), userName);
        AuthenticationToken token = new UsernamePasswordToken(userName, password);
        return super.hashProvidedCredentials(token, authenticationInfo).toString();
    }
}
